<template>
  <div class="app-container">
    <h3 class="text-center">数据刷新时间: {{ parseTime(refreshInfo.lastRefreshTime) }}</h3>
    <el-descriptions size="small" title="系统" border v-if="system">
      <el-descriptions-item label="操作系统">{{ system.name }} {{ system.version }}</el-descriptions-item>
      <el-descriptions-item label="体系架构">{{ system.arch }}</el-descriptions-item>
      <el-descriptions-item label="处理程序数">{{ system.availableProcessors }}</el-descriptions-item>
      <el-descriptions-item label="提交的虚拟内存">{{ formatSizeHuman(system.committedVirtualMemorySize) }}</el-descriptions-item>
      <el-descriptions-item label="物理内存">{{ formatSizeHuman(system.totalPhysicalMemorySize - system.freePhysicalMemorySize) }} / {{ formatSizeHuman(system.totalPhysicalMemorySize) }}</el-descriptions-item>
      <el-descriptions-item label="交换区大小">{{ formatSizeHuman(system.totalSwapSpaceSize - system.freeSwapSpaceSize) }} / {{ formatSizeHuman(system.totalSwapSpaceSize) }}</el-descriptions-item>
    </el-descriptions>

    <el-descriptions size="small" title="虚拟机" border class="margin-top" v-if="runtime">
      <el-descriptions-item label="名称">{{ runtime.name }}</el-descriptions-item>
      <el-descriptions-item label="虚拟机">{{ runtime.vmName }} {{ runtime.vmVersion }}</el-descriptions-item>
      <el-descriptions-item label="供应商">{{ runtime.vmVendor }}</el-descriptions-item>
      <el-descriptions-item label="进程CPU时间">{{ formatDuration(system.processCpuTime / 1000000) }}</el-descriptions-item>
      <el-descriptions-item label="总编译时间">{{ formatDuration(compilation.totalCompilationTime) }}</el-descriptions-item>
      <el-descriptions-item label="JIT 编译器">{{ compilation.name }}</el-descriptions-item>
      <el-descriptions-item label="启动时间">{{ (formatTime(runtime.startTime)) }}</el-descriptions-item>
      <el-descriptions-item label="运行时长">{{ formatDuration(runtime.uptime) }}</el-descriptions-item>
    </el-descriptions>

    <el-descriptions size="small" title="线程和类" border class="margin-top" v-if="thread">
      <el-descriptions-item label="活动线程">{{ thread.threadCount }}</el-descriptions-item>
      <el-descriptions-item label="峰值线程数">{{ thread.peakThreadCount }}</el-descriptions-item>
      <el-descriptions-item label="守护程序线程">{{ thread.daemonThreadCount }}</el-descriptions-item>
      <el-descriptions-item label="启动的线程总数">{{ thread.totalStartedThreadCount }}</el-descriptions-item>

      <el-descriptions-item label="已加装当前类">{{ classLoading.loadedClassCount }}</el-descriptions-item>
      <el-descriptions-item label="已加载类总数">{{ classLoading.totalLoadedClassCount }}</el-descriptions-item>
      <el-descriptions-item label="已卸载类总数">{{ classLoading.unloadedClassCount }}</el-descriptions-item>
    </el-descriptions>

    <el-descriptions size="small" title="堆信息" border class="margin-top" v-if="memory">
      <template v-if="memory.heapMemoryUsage">
        <el-descriptions-item label="当前堆大小">{{ formatSizeHuman(memory.heapMemoryUsage.used) }}</el-descriptions-item>
        <el-descriptions-item label="最大堆大小">{{ formatSizeHuman(memory.heapMemoryUsage.max) }}</el-descriptions-item>
        <el-descriptions-item label="提交的内存">{{ formatSizeHuman(memory.heapMemoryUsage.committed) }}</el-descriptions-item>
      </template>

      <el-descriptions-item label="暂挂最终处理">{{ memory.objectPendingFinalizationCount }}</el-descriptions-item>
    </el-descriptions>

    <el-row>
      <div v-for="garbageCollector in garbageCollectors" :key="garbageCollector.name">
        <dl>
          <dt class="" style="font-size: 15px;">垃圾回收器: {{ garbageCollector.name }} 收集次数: {{ garbageCollector.collectionCount }} 总花费时间: {{ formatDuration(garbageCollector.collectionTime) }}</dt>
          <dd style="line-height: 1.5;overflow-x: scroll;white-space: nowrap;margin-left: 10px;margin-top: 8px;">
            <!-- {{formatSizeHuman(garbageCollector.lastGcInfo.memoryUsageAfterGc[key].used)}} -->
            [GC] <span v-for="(value,key) in garbageCollector.lastGcInfo.memoryUsageBeforeGc" :key="key"> [{{ key }}: {{ formatSizeHuman(value.used) }} -> {{ formatSizeHuman(garbageCollector.lastGcInfo.memoryUsageAfterGc[key].used) }}] </span>
          </dd>
        </dl>
      </div>
    </el-row>

    <el-row>
      <el-col :span="8">
        <div class="padding">系统属性</div>
        <template v-if="runtime && runtime.systemProperties">
          <ul class="data-list" style="height: 50vh;overflow-y: scroll">
            <li v-for="(value ,key) in runtime.systemProperties" :key="key">{{ key }} = {{ value }}</li>
          </ul>
        </template>
      </el-col>
      <el-col :span="8">
        <div class="padding">设定的 VM 参数</div>
        <template v-if="flags">
          <ul class="data-list" style="height: 50vh;overflow-y: scroll">
            <li v-for="(flag) in flags" :key="flag.key+'flag'">{{ flag.key }} = {{ flag.value }}</li>
          </ul>
        </template>
      </el-col>
      <el-col :span="7" class="margin-left">
        <div class="padding">类路径数量: {{ classpaths.length }}</div>
        <el-table
          :data="classpaths"
          border
          stripe
          style="width: 100%"
          size="mini"
        >
          <el-table-column
            prop="path"
            label="类加载路径"
          />
        </el-table>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import jvm from '@/api/jvm'

import { formatSizeHuman, formatDuration, formatTime, parseTime } from '@/utils'
import vueJsonEditor from 'vue-json-editor'

export default {
  name: 'Dashboard',
  components: { vueJsonEditor },
  props: {
    connName: {
      type: String
    }
  },
  data() {
    return {
      system: {},
      runtime: {},
      compilation: {},
      thread: {},
      classLoading: {},
      memory: {},
      garbageCollectors: [],

      refreshInfo: {
        lastRefreshTime: null
      },

      flags: {}
    }
  },
  computed: {
    classpaths() {
      if (this.runtime && this.runtime.classPath) {
        return this.runtime.classPath.split(';').map(cp => ({ path: cp }))
      }
      return []
    }
  },
  mounted() {
  },
  methods: {
    formatSizeHuman, formatDuration, formatTime, parseTime,
    init() {
      if (this.connName) {
        this.refreshData()
      }
    },
    refreshData() {
      this.refreshInfo.lastRefreshTime = new Date().getTime()

      jvm.dashboard(this.connName).then(res => {
        if (res.data){
          this.system = res.data.system
          this.runtime = res.data.runtime
          this.compilation = res.data.compilation
          this.thread = res.data.thread
          this.classLoading = res.data.classLoading
          this.memory = res.data.memory
          this.flags = res.data.flags
          this.garbageCollectors = res.data.garbageCollectors || []
        }
      })
    },
    refreshModel() {
      this.refreshData()
    }
  }
}
</script>


